Global CalMutex:Int = CreateMutex()

Type CalLoader 
	
	Field loadedobject:Object
	Field loaded:Byte = False
	
	Method Load:Object(data:Object)
	
		loadedobject = Object(LoadBank(data))
		loaded = True
		Return loadedobject
		
	End Method
	
	Method IsLoaded:Byte()
		Return loaded
	End Method
	
	Method GetLoadedObject:Object()
		Return loadedobject
	End Method

End Type




Type CalLoaderHandler

	Const DATACALSKELETON:Int = 	0
	Const DATACALMESH:Int = 		1
	Const DATACALANIMATION:Int = 	2
	Const DATACALMORPHANIM:Int = 	3
	Const DATACALMATERIAL:Int = 	4
	Const DATACALIMAGE:Int =	 	5
	
	
	Field LoaderCallbacks:TList
	Field progress:Float

	Method New()
		LoaderCallbacks = New TList
	End Method
	
	
	Method LoadFile(url:String,TType:Int,loader:CalLoader,data:String="")
		
		'no need to reload our data if it's cached.
		Local havecallback:Byte = False
		
		For Local cb:CalLoadingCallback = EachIn LoaderCallbacks
		
			If cb.fileurl = url Then
				'Print "Have callback"
				havecallback = True
				'Exit
			EndIf
			
		Next
		If havecallback = False Then
			Local callback:CalLoadingCallback = New CalLoadingCallback
			callback.SetLoader(loader)
			callback.Load(TType,url,data)
			LoaderCallbacks.AddLast(callback)
		EndIf
		
		
	End Method
	
	Rem
	Method LoadData(url:String,TType:Int,loader:CalLoader,data:String="")
		Local callback:CalLoadDataBufferCallback = New CalLoadDataBufferCallback
		callback.SetLoader(loader)
		callback.Load(TType,url,data)
		LoaderCallbacks.AddLast(callback)
	End Method
	EndRem

	
	Method Update()
		For Local callback:CalLoadingCallback = EachIn LoaderCallbacks
			'callback.Update()
			progress = callback.percent
			If callback.IsFinished() = True And callback.loader.IsLoaded() = False Then
				callback.loader.Load(callback.data)
			EndIf
		Next
	End Method
	
	Method IsFileLoaded:Byte(url:String)
		For Local callback:CalLoadingCallback = EachIn LoaderCallbacks
			If callback.fileurl = url And callback.IsFinished() = True And callback.loader.IsLoaded() = True Then
				Return True
			EndIf
		Next	
		Return False
	End Method
	
	Method GetLoadedFile:Object(url:String,keepinlist:Byte=True)
		For Local callback:CalLoadingCallback = EachIn LoaderCallbacks
			If callback.fileurl = url And callback.IsFinished() = True And callback.loader.IsLoaded() = True Then
				If keepinlist = False Then
					LoaderCallbacks.Remove(callback)
				EndIf
				Return callback.GetLoadedObject()
			EndIf
		Next	
		Return Null	
	End Method
	
	
End Type


Type CalLoadingCallback
	
	Field get_req:tsendhttp
	Field post_req:tsendhttp
	Field hasheader:Byte = False
	Field headername:String
	Field headerval:String
	Field bytesrec:Int
	Field data:String
	Field finished:Byte = False
	Field datatype:Int
	Field fileurl:String
	Field loader:CalLoader
	Field percent:Float
	Field error:Byte = False
	Field Thread:Int
	Field killthread:Byte = False
	Field args:String[]
	
	Method GetLoadedObject:Object()
		Return loader.GetLoadedObject()
	End Method
	
	Method SetLoader(loadr:CalLoader)
		loader = loadr
	End Method
	
	Method GetLoader:CalLoader()
		Return loader
	End Method
	
	Method SetDataType(datat:Int)
		datatype = datat
	End Method
	
	Method GetDataType:Int()
		Return datatype
	End Method
	
	Method IsFinished:Byte()

		Return finished
	End Method
	
	Method GetData:String()
		Return data
	End Method
	
	Method OnHttpRequestComplete()
		'UpdateAsyncEvents
		
		'Print "Status: "+req.Status()
		'data = req.ResponseText()
		finished = True
		
		
	End Method
	
	Method SetHeader(name:String, value:String)
		headername = name
		headerval = val
		hasheader = True
	End Method
	
	Method RemoveHeader()
		headername = ""
		headerval = ""
		hasheader = False		
	End Method
	
	Method Update(progress:Float) 'Callback Function
			
		percent = progress
					
	End Method
	
	
	Method Load(TType:Int=0,url:String,sdata:String="",file:String="/wp-admin/admin-ajax.php")
		fileurl = url
		post_req = New tsendhttp
		
		Local vars:String[] = sdata.Split("&")
		
		For Local i:Int = 0 To vars.length-1
			Local values:String[] = vars[i].Split("=")
			post_req.addinput(values[0],values[1])
		Next
		Local data:String[] = post_req.send(url,80,file)	
		Local xmlbank:TBank = New TBank
		Local s:TStream = WriteFile(xmlbank)
		Local startxml:Int = 0
		For Local la:String = EachIn data
			DebugLog la
			If Instr(la,"<?xml") Then startxml = 1
			If startxml = 1 Then
				WriteLine s,la
			EndIf
		Next									
		CloseFile(s)
		Local callbackxml:xmlDocument = New xmlDocument
		callbackxml.Load(xmlbank)
		If callbackxml <> Null Then
			If callbackxml.Root().Name = "C3DX" Then	
				Local plnode:xmlNode = callbackxml.Root().FirstChild()
				If plnode <> Null Then
					If plnode.Attribute("file").value <> "" And Int(plnode.Attribute("id").value) > 0 Then
						If CopyFile2(plnode.Attribute("file").value,"cache/"+plnode.Attribute("id").value+".pak",Null) Then	'make a new callback
							finished = True
							loader.Load("cache/"+plnode.Attribute("id").value+".pak")
						Else
							error = True
							DebugLog "Could not save file, need admin permissions?"
						EndIf
					Else
						error=True
						DebugLog "Invalid pak returned from server"						
					EndIf
				Else
					error = True
					DebugLog "Invalid XML Response"	
				EndIf
			Else
				error = True
				DebugLog "Incomplete XML Response"		
			EndIf
		Else
			error = True
			DebugLog "Could not load Server Response XML"
		EndIf		
		killthread = True
		
	End Method

	Method LoadThreaded(TType:Int=0,url:String,data:String="",file:String="/wp-admin/admin-ajax.php")
		
		args = New String[4]
		args[0] = TType
		args[1] = url
		args[2] = data
		args[3] = file
		DetachThread(CreateThread(ThreadLoad,Object(Self)))
		
	End Method



End Type


	Function ThreadLoad:Object(o:Object)
		LockMutex(CalMutex)
			Local c:CalLoadingCallback = CalLoadingCallback(o)
			If c <> Null Then
				c.Load(Int(c.args[0]),c.args[1],c.args[2],c.args[3])
				'c.OnHttpRequestComplete()
				Return Object(c)
			EndIf
		UnlockMutex(CalMutex)
	End Function


